import { Transaction } from "tiny-entity2";
import { ApiDataContext } from "../domain/apiDataContext";
import { DataRegister } from "../domain/models/dataRegister";
import { BaseService } from "./baseService";
import { cRequest } from './../common/http/cRequest';

export class DataRegisterService extends BaseService {
    CreateDataRegister(entity: DataRegister, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new DataRegister();
            d.ConverToEntity(entity);
            d.createTime = Date.now();
            d.updateTime = Date.now();
            return ctx.Create(d);
        });
    }
    UpdateDataRegister(entity: DataRegister, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new DataRegister();
            d.ConverToEntity(entity);
            d.updateTime = Date.now();
            // d.version = Date.now();
            return ctx.Update(d);
        });
    }
    async GetDataRegisterById(id: string) {
        let ctx = new ApiDataContext();
        let dr = await ctx.DataRegister.First(x => x.id == $args1, { $args1: id });
    
        if (dr) {
            dr.datarPermits = await ctx.DataRPermits.Where(x => x.dataRegisterId == $args1, { $args1: dr.id }).ToList();
        }

        return dr;
    }

    async QueryDataRegister(params): Promise<{ list: DataRegister[]; total: number; }> {
        let ctx = new ApiDataContext();
        let whereSql = [];

        let limitSql = '';
        if (params.pageIndex && params.countOfPage) {
            limitSql = `limit ${params.countOfPage * (params.pageIndex - 1)},${params.countOfPage}`;
        }

        for (let key in params) {
            if (key == 'pageIndex' ||
                key == 'countOfPage') {
                continue;
            }
            if (key == 'dataType' ||
                key == 'objectId' ||
                key == 'objectType' ||
                key == 'parentDataRegisterId' ||
                key == 'orgId' ||
                key == 'status'
            ) {
                whereSql.push(`${key}='${params[key]}'`);
            }
            else if (key == 'userId') {
                if (params[key]) {
                    whereSql.push(`(userIds LIKE '%${params[key]}%' OR userIds IS NULL)`);
                }
            }
            else {
                if (key.indexOf('beginTime') > -1) {
                    let t = key.split('.');
                    whereSql.push(`data -> '$.fields."${t[0]}".ts' >= ${params[key]}`);
                }
                else if (key.indexOf('endTime') > -1) {
                    let t = key.split('.');
                    whereSql.push(`data -> '$.fields."${t[0]}".ts' < ${params[key]}`);
                }
                else {
                    whereSql.push(`data -> '$.fields."${key}"' like '%${params[key]}%'`);
                }
            }

        }

        let sql = `select * from dataregister where ${whereSql.join(' AND ')} ORDER BY createTime DESC ${limitSql} ;`;
        let sql2 = `select count(id) as total from dataregister where ${whereSql.join(' AND ')};`;

        let totalRow = await ctx.Query(sql2);
        let list = await ctx.Query(sql);

        let total = totalRow[0].total;

        return {
            total,
            list
        }
    }

    async GetDataRegisterByDataTypeAndObjectId(dataType: string, objectId: string) {
        let ctx = new ApiDataContext();
        return ctx.DataRegister.First(x => x.dataType == $args1 && x.objectId == $args2, { $args1: dataType, $args2: objectId });
    }

    DeleteDataRegistr(id: string, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            return ctx.Delete<DataRegister>(x => x.id == $args1, ctx.DataRegister, { $args1: id });
        });
    }

    DeleteDataRegisterByObjectId(objectId: string, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            return ctx.Delete<DataRegister>(x => x.objectId == $args1, ctx.DataRegister, { $args1: objectId });
        });
    }

    async dataSync(projectId: string, ctx?: ApiDataContext){
        ctx || (ctx = new ApiDataContext());
        let nkData: { data: IGYSOrder[]; } = await cRequest.Current.Get<any>(`http://filegennet5.zepride.com/YouJianDataSync/GetSupplierSignUp?ProjectId=${projectId}`);
        let result=0;
       // const ctx = new ApiDataContext();
        for (let item of nkData.data) {
           // console.log("dataSyncStartValueItem:",item);
            try {
                const dataRegister = await ctx.DataRegister.First(x => x.id == $args1, { $args1: item.YouJianProjectId });
              //  console.log("dataSyncDataRegister:",dataRegister);
                if (dataRegister) {
                    for (const key in dataRegister.data.fields) {
                        let value = dataRegister.data.fields[key];
                        if (!value) continue;
                        if (!Array.isArray(value)) continue;
                        if (value.length == 0) continue;

                        let valueItem = value[0];
                        if (typeof valueItem != 'object') continue;
                        const valueItemKeys = Object.keys(valueItem);
                        const hasPackageInfo = valueItemKeys.find(x => x == 'YouJianPackageId');
                        if (!hasPackageInfo) continue;
                        
                        try {
                            valueItem = value.find(x => x.YouJianPackageId == item.YouJianPackageId);

                            valueItem.Supplier || (valueItem.Supplier = []);
                           // const has = valueItem.Supplier.find(x => x.Id == item.Id);
                            const has = valueItem.Supplier.find(x => x.SupplierName == item.SupplierName && valueItem.YouJianPackageId==item.YouJianPackageId);
                            result+=1;
                            if (!has) {
                                valueItem.Supplier.push(item);
                            }

                           // console.log("valueItem:",valueItem,item);
                        }
                        catch (error) {
                            result=0;
                            console.log(error);
                        }
                    }

                    await ctx.Update(dataRegister);
                }
            }
            catch (error) {
                result=0;
                console.log(error);
            }
        } 
        return {result:result};
    }

    async contractDataSync(projectId: string, ctx?: ApiDataContext){
        ctx || (ctx = new ApiDataContext());
        let nkData: { data: IGYSSupplierContract[]; } = await cRequest.Current.Get<any>(`http://filegennet5.zepride.com/YouJianDataSync/GetProjectResult?ProjectId=${projectId}`);
        let result=0;
       // const ctx = new ApiDataContext();
        for (let item of nkData.data) {
           // console.log("dataSyncStartValueItem:",item);
            try {
                const dataRegister = await ctx.DataRegister.First(x => x.id == $args1, { $args1: item.YouJianProjectId });
                if (dataRegister) {
                    for (const key in dataRegister.data.fields) {
                        let value = dataRegister.data.fields[key];
                        if (!value) continue;
                        if (!Array.isArray(value)) continue;
                        if (value.length == 0) continue;

                        let valueItem = value[0];
                        if (typeof valueItem != 'object') continue;
                        const valueItemKeys = Object.keys(valueItem);
                        const hasPackageInfo = valueItemKeys.find(x => x == 'YouJianPackageId');
                        if (!hasPackageInfo) continue;
                        
                        try {
                            valueItem = value.find(x => x.YouJianPackageId == item.YouJianPackageId);

                            valueItem.SupplierContract || (valueItem.SupplierContract = []);
                           // const has = valueItem.Supplier.find(x => x.Id == item.Id);
                            const has = valueItem.SupplierContract.find(x => x.SupplierName == item.SupplierName && valueItem.YouJianPackageId==item.YouJianPackageId);
                            result+=1;
                            if (has) {
                                valueItem.SupplierContract=[];
                            }
                            valueItem.SupplierContract.push(item);
                           // console.log("valueItem:",valueItem,item);
                        }
                        catch (error) {
                            result=0;
                            console.log(error);
                        }
                    }

                    await ctx.Update(dataRegister);
                }
            }
            catch (error) {
                result=0;
                console.log(error);
            }
        }
        return {result:result};
    }
}

export interface IGYSOrder {
    "Id": number;
    "ProjectId": any;
    "YouJianProjectId": string;
    "PackageId": number;
    "YouJianPackageId": string;
    "OrganizationId": string;
    "OrganizationalCode": string;
    "SupplierName": string;
    "Attachment": string;
    "EnterStatus": number;
    "EnterTime": string;
    "EnterMethod": string;
    "DealUserName": string;
    "Mobile": string;
    "Post": string;
    "Email": string;
    "MailAddress": string;
    "DealUserNameIdCard": string;
    "BatchNum": string;
    "ProjectName": string;
    "PayDateTime": string;
    "DataType": number;
    "ReportNum": number;
    "ProjectNeedFile": string;
    "RegTable": string;
    "LetterOfIntroduction": string;
    "OrderNumber": string;
    "Money": number,
    "CreateDateTime": string;
    "Status": number;
    "IsPersonPay": number;
    "SupplierRegisteredAddress": string;
}

export interface IGYSSupplierContract {
    "YouJianProjectId": string;
    "YouJianPackageId": string;
    "PackageNum": string;
    "SupplierName": string;
    "ContractFile": string;
    "ContractStatus": string;
    "ContractStatusValue":string;
    "ProjectId":string;
}

export interface IRedisProjectMsg {
    ProjectId: string;
    OrganizationId: number
    isDone?: boolean;
}